#include "Texture.h"
#include <cmath>

	
Texture::Texture(Color* bitmap, int width, int height) :
	m_Bitmap( bitmap ),
	m_Width( width ), m_Height( height )
{
}

void Texture::readImage(std::string file)
{
	FILE* f = fopen(file.c_str(), "rb");
	if (f)
	{
		// read width and height from file header
		unsigned char buffer[20];
		fread(buffer, 1, 20, f);
		m_Width = *(buffer + 12) + 256*(*(buffer + 13));
		m_Height = *(buffer + 14) + 256*(*(buffer + 15));
		fclose(f);
		
		// read actual image
		f = fopen(file.c_str(), "rb");
		unsigned char* image = new unsigned char[m_Width * m_Height * 3 + 1024];
		fread(image, 1, m_Width * m_Height * 3 + 1024, f);
		fclose(f);
		
		// convert RGB pixel data to double RGB
		m_Bitmap = new Color[m_Width * m_Height];
		double convert = 1.0 / 256;
		for (int size = m_Width * m_Height, i = 0;i < size;i++)
			m_Bitmap[i] = Color(image[i*3+20]*convert, image[i*3+19]*convert, image[i*3+18]*convert);
		delete image;
	}
}

int roundaway(double d){
	if(d > doubleResolution)
		return 1;
	if(d < -doubleResolution)
		return -1;
	return 0;
}

Color Texture::GetPixel(double u, double v)
{
	double fu, fv;
	// calculate fractional parts of u and v
	double fracu = modf((u + 1000.5) * m_Width, &fu);
	double fracv = modf((v + 1000.0) * m_Width, &fv);
	int u1 = ((int)fu) % m_Width;
	u1 = u1 < 0 ? u1 + m_Width : u1;
	int v1 = ((int)fv) % m_Height;
	v1 = v1 < 0 ? v1 + m_Height : v1;
	int u2 = ((u1 + roundaway(fracu)) + m_Width) % m_Width;
	int v2 = ((v1 + roundaway(fracv)) + m_Height) % m_Height;
	
	// calculate weight factors
	double absfracu = std::abs(fracu), absfracv = std::abs(fracv);
	double w1 = (1 - absfracu) * (1 - absfracv);
	double w2 = absfracu * (1 - absfracv);
	double w3 = (1 - absfracu) * absfracv;
	double w4 = absfracu *  absfracv;
	
	// get four pixels from the texture
	Color c1 = m_Bitmap[u1 + v1 * m_Width];
	Color c2 = m_Bitmap[u2 + v1 * m_Width];
	Color c3 = m_Bitmap[u1 + v2 * m_Width];
	Color c4 = m_Bitmap[u2 + v2 * m_Width];
	
	// scale and sum the four colors
	return c1 * w1 + c2 * w2 + c3 * w3 + c4 * w4;
}
